package com.teamwings.ctrls.controller;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.teamwings.common.aspect.FormControlMap;
import com.teamwings.common.constant.FormConstant;
import com.teamwings.common.exception.ResultException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.apache.commons.lang.StringUtils;
import com.teamwings.common.vo.Result;
import com.teamwings.ctrls.FormComponent;
import com.teamwings.ctrls.entity.OatAppCode;
import com.teamwings.ctrls.entity.OatAppExchangeUnit;
import com.teamwings.ctrls.entity.OatUserSms;
import com.teamwings.ctrls.service.AppService;
import com.teamwings.ctrls.service.ILogicTableService;
import com.teamwings.ctrls.service.OatAppExchangeUnitService;
import com.teamwings.ctrls.service.OatUserSmsService;
import com.teamwings.enums.CtrlTypeEnum;
import com.teamwings.modules.page.service.IPageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.system.api.ISysDepartServiceFeign;
import org.jeecg.common.system.api.ISysUserServiceFeign;
import org.jeecg.common.system.api.entity.SysUser;
import org.jeecg.common.system.vo.ComboModel;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.SysDepartTreeModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import java.util.Optional;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author jobob
 * @since 2021-05-05
 */
@RestController
@Api(tags = "控件数据查询")
public class FormCtrlController {

    @Autowired
    private ISysBaseAPI iSysBaseAPI;
    @Autowired
    private AppService appService;
    @Autowired
    private OatAppExchangeUnitService oatAppExchangeUnitService;
    @Autowired
    private OatUserSmsService oatUserSmsService;
    @Autowired
    private ILogicTableService logicTableService;
    @Autowired
    private ISysDepartServiceFeign sysDepartServiceFeign;
    @Autowired
    private ISysUserServiceFeign sysUserServiceFeign;
    @Autowired
    private ISysBaseAPI sysBaseAPI;
    @Autowired
    private IPageService pageService;
    /**
     * 分页查询
     */
    /*@ApiOperation(value = "获取数据字典", notes = "获取数据字典")
    @GetMapping(value = "/list")
    public Result<?> list() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //IOatAppDictItemService oatAppDictItemServiceImpl = SpringContextUtil.getBean("oatAppDictItemServiceImpl", IOatAppDictItemService.class);

        *//*Class c = Class.forName("com.teamwings.ctrls.service.impl.OatAppDictItemServiceImpl");
        Method load = c.getMethod("load");
        load.invoke(oatAppDictItemServiceImpl,null);
        System.out.println();*//*
     *//*String className = "OatAppDictItem";
        Class<?> ServiceImplType = Class.forName("com.teamwings.ctrls.service.impl."+className+"ServiceImpl");
        Class<?> entityType = Class.forName("com.teamwings.ctrls.service.IOatAppDictItemService");
        //反射设置方法参数。
        Method method = ServiceImplType.getDeclaredMethod("load");
        //在ApplicationContext中根据class取出已实例化的bean
        method.invoke(SpringContextUtil.getApplicationContext().getBean(ServiceImplType));*//*

        return Result.OK();
    }*/

    /**
     * 控件Post方式API调用入口
     * 取消了method方法参数名
     * 直接使用requestybody中的参数作为数据传入，由控件自行根据参数判断操作
     * <p>
     * 调用示例
     *
     * @param ctrlType
     * @param params
     */
    @ApiOperation(value = "控件通用调用入口POST版本", notes = "")
    @PostMapping(value = "/form/ctrl/{ctrlType}")
    public Result<?> api(
            @PathVariable("ctrlType") String ctrlType,
            @RequestBody(required = false) String params
    ) {
        // 获取控件调用入口
        if (FormControlMap.typeClassMap.containsKey(ctrlType) || FormControlMap.noFieldClassMap.containsKey(ctrlType)) {
            Class<?> aClass = null;
            try {
                String classname = FormControlMap.typeClassMap.get(ctrlType);
                if (classname == null || classname.equals("")) {
                    classname = FormControlMap.noFieldClassMap.get(ctrlType);
                }
                aClass = Class.forName(classname);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                return Result.error("找不到名称 “" + ctrlType + "” 的调用入口。");
            }
            FormComponent component = null;
            try {
                component = (FormComponent) aClass.getDeclaredConstructor().newInstance();
            } catch (InstantiationException | IllegalAccessException
                    | InvocationTargetException | NoSuchMethodException e) {
                e.printStackTrace();
                return Result.error("找不到实现 “" + ctrlType + "” 的调用入口。");
            }
            Result<?> ret = component.trigger(FormConstant.TRIGGER_TYPE.CTRL_HANDLER,
                    pageService, null, params);

            if (ret == null) {
                return Result.error("处理失败");
            } else if (ret.getIsVoid()) {
                return null;
            } else {
                return ret;
            }
            //if (ret.isSuccess()) {
            //    return Result.ok("处理成功");
            //} else {
            //    return Result.error("处理失败");
            //}
        } else {
            return Result.error("找不到“" + ctrlType + "”的调用入口。");
        }
    }

    /**
     * 根据菜单配置，获取绑定了表单的流程图ID
     * @param formHeadId
     * @return
     */
    @GetMapping("/form/flowMapId/{menuId}/{headId}")
    @ApiOperation(value = "获取流程图ID", notes = "根据菜单配置，获取绑定了表单的流程图ID")
    public Result<?> findFlowMap(@PathVariable("headId") String formHeadId, @PathVariable("menuId") String menuId) {
        JdbcTemplate jdbcTemplate = pageService.getJdbcTemplate();
        String sql = "";
        Object[] params = new Object[1];

        boolean menuIsNotNull = menuId != null && !menuId.isEmpty() && !menuId.trim().isEmpty();
        boolean headIdIsNotNull = formHeadId != null && !formHeadId.isEmpty();

        if (menuIsNotNull) {
            sql = "SELECT MAX(flow_id) FROM sys_permission WHERE id = ?" +
                    " AND flow_id is not null";
            params[0] = menuId;
        } else if (headIdIsNotNull) {
            sql = "SELECT MAX(flow_id) FROM sys_permission " +
                    "WHERE form_table_head_id = ? AND flow_id is not null";
            params[0] = formHeadId;
        } else {
            return Result.error("参数不足。");
        }

        String flow_id;
        try {
            flow_id = jdbcTemplate.queryForObject(sql, params, String.class);
        }catch(EmptyResultDataAccessException ex) {
            return Result.error("获取流程图失败，该表单还没有在菜单中关联流程图。");
        }
        if (flow_id != null && !flow_id.isEmpty()) {
            return Result.OK(flow_id);
        } else {
            return Result.error(flow_id);
        }
    }

    /**
     * 获取各控件的基础数据
     *
     * @param formId   表单id
     * @param ctrlType 控件类型
     * @param ctrlId   分类id
     * @param method   方法名
     * @param itemKey  子类id
     * @return
     */
    @Deprecated
    @ApiOperation(value = "获取字典列表-提供给报表项目", notes = "获取字典列表-提供给报表项目")
    @GetMapping(value = {"/form/ctrl/{formId}/{ctrlType}/{ctrlId}/{method}/{itemKey}",
            "/form/ctrl/{ctrlType}/{method}/{itemKey}",
            "/form/ctrl/{ctrlType}/{method}"
    })
    public Result<?> list1(@PathVariable(value = "formId", required = false) String formId,
                           @PathVariable(value = "ctrlType") String ctrlType,
                           @PathVariable(value = "ctrlId", required = false) String ctrlId,
                           @PathVariable(value = "method") String method,
                           @PathVariable(value = "itemKey", required = false) String itemKey,
                           HttpServletRequest request
    ) {

        Integer type = Optional.ofNullable(CtrlTypeEnum.getCode(ctrlType))
                .orElseThrow(() -> new ResultException("没有找到对应的控件类型"));

        switch (type) {
            // oaDict
            case 1:
                List<DictModel> dictModels = null;
                if ("load".equals(method)) {
                    dictModels = iSysBaseAPI.queryAllDict();
                }
                if ("loadItem".equals(method)) {
                    dictModels = iSysBaseAPI.queryDictItemsByCode(itemKey);
                }
                return Result.OK(dictModels);
            // oaDoctype
            case 2:
                List<OatAppCode> appCodes = null;
                if ("load".equals(method)) {
                    appCodes = appService.list();
                }
                return Result.OK(appCodes);
            // oaDept
            case 3:
                List<SysDepartTreeModel> allSysDepart = null;
                if ("load".equals(method)) {
                    // cloud api
                    //allSysDepart = iSysBaseAPI.getAllSysDepartWithTree();
                }
                return Result.OK(allSysDepart);
            // oaUser
            case 4:
                List<ComboModel> comboModels = null;
                if ("load".equals(method)) {
                    comboModels = iSysBaseAPI.queryAllUserBackCombo();
                }
                return Result.OK(comboModels);
            // oaComment
            case 5:
                List<OatUserSms> oatUserSms = null;
                if ("load".equals(method)) {
                    QueryWrapper queryWrapper = new QueryWrapper<>().orderBy(true, true, "F_SORT");
                    oatUserSms = oatUserSmsService.list(queryWrapper);
                }
                return Result.OK(oatUserSms);
            // oaSendDept
            case 6:
                List<SysDepartTreeModel> allSysDepartList = null;
                if ("load".equals(method)) {
                    // cloud api
                    //allSysDepartList = iSysBaseAPI.getAllSysDepartWithTree();
                }
                return Result.OK(allSysDepartList);
            // oaSendUser
            case 7:
                List<ComboModel> comboModelList = null;
                if ("load".equals(method)) {
                    comboModelList = iSysBaseAPI.queryAllUserBackCombo();
                }
                return Result.OK(comboModelList);
            // oaUnit
            case 8:
                List<OatAppExchangeUnit> oatAppExchangeUnits = null;
                if ("load".equals(method)) {
                    oatAppExchangeUnits = oatAppExchangeUnitService.list();
                }
                return Result.OK(oatAppExchangeUnits);
            // oaTable
            case 9:
                return null;
            // oaLogicTable
            case 11:
                List<Map<String, String>> maps = null;
                if ("tableList".equals(method)) {
                    String searchText = request.getParameter("searchText");
//                    if (StringUtils.isEmpty(searchText)) {
//                        return Result.error("请输入要搜索的表名");
//                    }
                    maps = logicTableService.tableList(searchText);
                    return Result.OK("获取自定义表单列表成功", maps);
                }
                if ("formList".equals(method)) {
                    maps = logicTableService.tableList(false);
                    return Result.OK("获取自定义表单列表成功", maps);
                }
                // 根据sql获取对应字段
                if ("getColumnBySql".equals(method)) {
                    String sql = request.getParameter("sql");
                    List<String> list = logicTableService.getColumnBySql(sql);
                    return Result.OK("获取自定义表单列表成功", list);
                }
                return Result.error("获取" + method + "失败");
            // oaSendUserByDept
            case 12:
                if ("queryUserByDepId".equals(method)) {
                    String jsonString = sysUserServiceFeign.queryUserByDepId(request.getParameter("id"), request.getParameter("realname"));
                    return JSON.parseObject(jsonString, Result.class);
                } else if ("getUserList".equals(method)) {
                    SysUser sysUser = new SysUser();
                    String username = request.getParameter("username");
                    sysUser.setUsername(username);
                    String jsonString = sysUserServiceFeign.queryPageList(sysUser, request.getParameter("pageNo"), request.getParameter("pageSize"));
//                    return JSON.parseObject(jsonString, new TypeReference<Result<List<SysUser>>>() {});
                    return JSON.parseObject(jsonString, Result.class);
                } else if ("queryTreeList".equals(method)) {
                    String id = request.getParameter("id");
                    String jsonString = sysDepartServiceFeign.queryTreeList(id, request.getParameter("realname"));
                    return JSON.parseObject(jsonString, Result.class);
                } else {
                    return Result.error("获取" + method + "失败");
                }
        }

        return null;
    }


}
